package com.smit.icast;

import android.app.PendingIntent;
import android.content.Context;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;

import com.smit.adapter.DVBDevice;
import com.smit.utils.LogUtil;

import java.util.HashMap;

/**
 * icast device
 */
public class ICastDevice extends DVBDevice {
    /** DVB 设备VID */
    public static final int CAM_USB_VID = 10719;
    /** DVB 设备PID */
    public static final int CAM_USB_PID = 1;

    private static final String TAG = "ICastDevice";
    private int deviceDetachTimeOut = 0;
    private UsbManager usbManager;
    private Context context;
    private int resetStatus = 0;

    /**
     * 构造函数
     * @param context Android application context
     */
    public ICastDevice(Context context) {
        this.context = context;
        this.usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
    }

    /**
     * 获取icast dongle设备
     * @return icast dongle设备
     */
    public UsbDevice getCamUsbDevice() {
        LogUtil.debug(TAG, "camUsbDevice start>>>");
        if (usbManager == null) {
            LogUtil.error(TAG, "camUsbDevice usbManager == null");
            return null;
        }
        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
        if (deviceList != null && deviceList.size() == 0) {
            LogUtil.error(TAG, "camUsbDevice No cam usb device found!");
            return null;
        }
        for (UsbDevice device : deviceList.values()) {
            if (checkCamUsb(device.getProductId(), device.getVendorId())) {
                LogUtil.debug(TAG, "camUsbDevice yes!");
                return device;
            }
        }
        LogUtil.debug(TAG, "camUsbDevice fail!");
        LogUtil.debug(TAG, "camUsbDevice end<<<");
        return null;
    }

    /**
     * 获取设备ID
     * @return 设备fd
     */
    public int getDeviceFd() {
        LogUtil.debug(TAG, "getDeviceFd start>>>");
        int fd = 0;
        UsbDevice device = getCamUsbDevice();
        if (device == null) {
            LogUtil.error(TAG, "getDeviceFd device is null");
            return 0;
        }
        UsbDeviceConnection camUsbConnection = usbManager.openDevice(device);
        if (device.getInterfaceCount() > 0
                && camUsbConnection != null
                && !camUsbConnection.claimInterface(device.getInterface(0), true)) {
            LogUtil.error(TAG, "getDeviceFd claimInterface error");
            return 0;
        }
        fd = camUsbConnection.getFileDescriptor();
        LogUtil.debug(TAG, "getDeviceFd fd = " + fd);
        LogUtil.debug(TAG, "getDeviceFd end<<<");
        return fd;
    }

    /**
     * 检测是否存在dongel设备
     * @param pId dongle设备PID
     * @param vId dongle设备VID
     * @return true 存在，false不存在
     */
    public boolean checkCamUsb(final int pId, final int vId) {
        if (CAM_USB_PID == pId && CAM_USB_VID == vId) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 设置dongle被拔出消息延迟发送时间，为了解决dongle自己复位，UI上有不想显示dongle被复位
     * @param timeout 超时时间(ms)
     */
    public void setDetachTimeOut(int timeout) {
        LogUtil.error(TAG, "setDetachTimeOut timeout=" + timeout);
        deviceDetachTimeOut = timeout;
    }

    /**
     * 获取拔掉超时时间
     * @return 超时时间
     */
    public int getDetachTimeOut() {
        return deviceDetachTimeOut;
    }

    /**
     * 是否设备资源
     */
    public void releaseDevice() {
        LogUtil.debug(TAG, "releaseDevice");
    }

    /**
     * 申请设备访问权限
     * @param device usb设备
     * @param intent 回调intent
     */
    public void requestPermission(UsbDevice device, PendingIntent intent) {
        usbManager.requestPermission(device, intent);
    }

    /**
     * 复位DVB设备
     */
    public void reset() {
        LogUtil.debug(TAG, "resetCamUsb start>>>");
        UsbDevice device = getCamUsbDevice();
        resetUsbDevice(device);
        LogUtil.debug(TAG, "resetCamUsb end<<<");
    }

    /**
     * 复位指定USB设备
     * @param device USB设备
     */
    private void resetUsbDevice(UsbDevice device) {
        LogUtil.debug(TAG, "resetUsbDevice start>>>");
        LogUtil.debug(TAG, "resetUsbDevice~~~resetStatus=" + getStatus());
        //UsbDevice device = getDevice();
        if (device == null) {
            LogUtil.error(TAG, "resetUsbDevice device is null");
            return;
        }
        UsbDeviceConnection camUsbConnection = usbManager.openDevice(device);
        if (device.getInterfaceCount() > 0
                && camUsbConnection != null
                && !camUsbConnection.claimInterface(device.getInterface(0), true)) {
            LogUtil.error(TAG, "resetUsbDevice claimInterface error");
            return;
        }
        LogUtil.debug(TAG, "reset >>>");
        setStatus(DVBDevice.DVB_DEVICE_IS_RESETTING);
        camUsbConnection.controlTransfer(0x40, 0xA0, 0, 0, null, 0, 100);
        LogUtil.debug(TAG, "reset <<<");
        LogUtil.debug(TAG, "resetUsbDevice end<<<");
        return;
    }

    /**
     * 判断usb设备是否有访问权限
     * @param device usb设备
     * @return true有权限，false无权限
     */
    public boolean hasPermission(UsbDevice device) {
        if (device == null || usbManager == null) {
            LogUtil.error(TAG, "hasPermission device == null || mUsbManager == null");
            return false;
        }
        if (usbManager.hasPermission(device)) {
            LogUtil.debug(TAG, "hasPermission yes!");
            return true;
        }
        return false;
    }

    /**
     * 复位设备
     */
    @Override
    public void resetDevice() {
        LogUtil.debug(TAG, "resetCamUsb start>>>");
        UsbDevice device = getCamUsbDevice();
        resetUsbDevice(device);
        LogUtil.debug(TAG, "resetCamUsb end<<<");
    }

    /**
     * 检测设备
     */
    @Override
    public void detectDevice() {

    }

    /**
     * 设备是否连接
     * @return true连接，false未连接
     */
    @Override
    public boolean isConnected() {
        if (usbManager == null) {
            LogUtil.error(TAG, "isAttached usbManager == null");
            return false;
        }
        HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
        if (deviceList != null && deviceList.size() == 0) {
            LogUtil.error(TAG, "isAttached No cam usb device found!");
            return false;
        }
        for (UsbDevice device : deviceList.values()) {
            if (checkCamUsb(device.getProductId(), device.getVendorId())) {
                //LogUtil.debug(TAG, "isAttached true!");
                return true;
            }
        }
        return false;
    }
}